﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Microsoft.Security.Application;
using qkview.Models;
using WebMatrix.WebData;

namespace qkview.Controllers
{
    [Authorize] 
    public class ApiNoteController : ApiController
    {
        private QKVEntities db = new QKVEntities();

        // GET api/ApiNote
        public IEnumerable<NoteDto> GetNotes(string boardID)
        {
            int bID = Convert.ToInt32(Common.Decode(boardID));  
            var notes = db.Notes.Include(n => n.Board).Include(t=>t.Theme).Where(x=>x.BoardID == bID).AsEnumerable()
                .Select(x=>new NoteDto(x));
            return notes.AsEnumerable();
        }

        //// GET api/ApiNote/5
        //public Note GetNote(int id)
        //{
        //    Note note = db.Notes.Find(id);
        //    if (note == null)
        //    {
        //        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        //    }

        //    return note;
        //}

        // PUT api/ApiNote/5

        public HttpResponseMessage PutNote(string id, NoteDto note)
        {
            if (!ModelState.IsValid)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
            
            if (id != note.NoteID)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }
            
            String slug;
            Note noteorg = db.Notes.Find(Convert.ToInt32(Common.Decode(id)));
            Note noteNew = note.ToEntity();

            if (noteorg.Board.UserID != WebSecurity.CurrentUserId)
            {
                return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Permission denied");
            }                       
            noteorg.Title = noteNew.Title;
            noteorg.Description = HtmlUtility.RemoveInvalidHtmlTags(noteNew.Description ?? "");
            foreach (Section section in noteNew.Sections) {
                Section sec = noteorg.Sections.First(x => x.SectionID == section.SectionID);
                sec.Title = section.Title;
                sec.Summary = section.Summary; 
                sec.Description = HtmlUtility.RemoveInvalidHtmlTags(section.Description ?? "") ;
                //sec.Description = HtmlUtilityJeff.Sanitize(section.Description ?? "");
                if (String.IsNullOrEmpty(sec.URLSlug)) {
                    slug = Common.GenerateSlug(sec.Title);
                    int slugSuffix = db.Sections.Count(x => x.Note.BoardID  == sec.Note.BoardID &&  x.URLSlug == slug);
                    if (slugSuffix > 0)
                    {
                        slug += "-" + sec.SectionID.ToString("X");
                    }
                    sec.URLSlug = slug;
                    //Multiple section has same title so need to save section on each iteration to avoid duplicate url slug
                    try
                    {
                        db.SaveChanges();
                    }
                    catch (DbUpdateConcurrencyException ex)
                    {
                        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
                    }

                }
            } 
           

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        // POST api/ApiNote
        public HttpResponseMessage PostNote(NoteDto note)
        { 
            Note obj = note.ToEntity();

            var userID = db.Boards.FirstOrDefault(x=>x.BoardID == obj.BoardID).UserID;
            if (userID != WebSecurity.CurrentUserId) {
                return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Permission denied");
            }
            UserSetting us = db.UserSettings.FirstOrDefault(x => x.UserProfile.UserName == User.Identity.Name);
            int allowedNotes = us.TotalNotes;
            if (db.Notes.Count(x => x.BoardID == obj.BoardID) >= allowedNotes)
            {
                ModelState.AddModelError("error", "Please upgrade your account to create more Notes.");               
            }          

            if (ModelState.IsValid)
            {
             
                obj.CreatedDate = DateTime.UtcNow; 
                db.Notes.Add(obj);
                db.SaveChanges();
                note.NoteID =Common.Encode(obj.NoteID.ToString());
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, note);
                //response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = obj.NoteID }));
                return response;
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }

        // DELETE api/ApiNote/5
        public HttpResponseMessage DeleteNote(string id)
        {
            Note note = db.Notes.Find(Convert.ToInt32(Common.Decode(id)));
            if (note == null)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
            if (note.Board.UserID != WebSecurity.CurrentUserId)
            {
                return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Permission denied");
            }  
            db.Notes.Remove(note);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}